<?php
namespace app\controller;

use think\Request;
use app\BaseController;
use app\model\Reminder;
use app\model\User;
use app\model\SystemConfig;
use PHPMailer\PHPMailer\PHPMailer;
use think\facade\Log;
use Swoole\Coroutine;
use Swoole\Coroutine\WaitGroup;

class TaskController extends BaseController
{
    /**
     * 发送到期提醒（Curl并发版本）
     */
    public function sendReminders()
    {
        try {
            $reminders = Reminder::where('is_finished', 0)
                ->where('is_disabled', 0)
                ->where('delete_time', null)
                ->where('due_date', '<=', date('Y-m-d H:i:s'))
                ->where('is_finished', 0)
                ->select();

            if ($reminders->isEmpty()) {
                return json(['status' => 200, 'message' => '没有需要发送的提醒']);
            }

            
            // 将提醒分批处理
            $chunks = array_chunk($reminders->toArray(), 20); // 每批20个
            $results = [];
            
            foreach ($chunks as $chunk) {
                // 创建多个curl句柄
                $multiCurl = curl_multi_init();
                $channels = [];
                $site_url = SystemConfig::getConfig('site_url');
                // return json($site_url);
                
                // 为每个提醒创建一个curl请求
                foreach ($chunk as $reminder) {
                    $url = $site_url . '/task/send_single_reminder';
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, [
                        'reminder_id' => $reminder['id']
                    ]);
                    
                    curl_multi_add_handle($multiCurl, $ch);
                    $channels[] = $ch;
                }

                // 执行批量请求
                $active = null;
                do {
                    $mrc = curl_multi_exec($multiCurl, $active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);

                while ($active && $mrc == CURLM_OK) {
                    if (curl_multi_select($multiCurl) == -1) {
                        usleep(100);
                    }
                    do {
                        $mrc = curl_multi_exec($multiCurl, $active);
                    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
                }

                // 获取结果
                foreach ($channels as $ch) {
                    $result = json_decode(curl_multi_getcontent($ch), true);
                    $results[] = $result;
                    curl_multi_remove_handle($multiCurl, $ch);
                }

                curl_multi_close($multiCurl);
            }

            // 统计结果
            $successCount = count(array_filter($results, fn($r) => $r['success']));
            $failCount = count($results) - $successCount;
            $errors = array_column(
                array_filter($results, fn($r) => !$r['success']),
                'error'
            );

            return json([
                'status' => 200,
                'message' => '提醒发送任务完成',
                'data' => [
                    'total' => count($results),
                    'success' => $successCount,
                    'fail' => $failCount,
                    'errors' => $errors
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('发送提醒任务失败: ' . $e->getMessage());
            return json(['status' => 500, 'message' => '发送提醒任务失败：' . $e->getMessage()]);
        }
    }

    /**
     * 发送单个提醒（供并发调用）
     */
    public function sendSingleReminder(Request $request)
    {
        try {
            $reminderId = $request->post('reminder_id');
            $reminder = Reminder::find($reminderId);
            
            if (!$reminder) {
                return json([
                    'success' => false,
                    'error' => "提醒ID {$reminderId} 不存在"
                ]);
            }

            $user = User::find($reminder->user_id);
            if (!$user || !$user->email) {
                return json([
                    'success' => false,
                    'error' => "提醒ID {$reminderId}: 用户不存在或邮箱为空"
                ]);
            }

            // 获取邮件配置
            $mailConfig = [
                'host' => SystemConfig::getConfig('mail_host'),
                'port' => SystemConfig::getConfig('mail_port'),
                'username' => SystemConfig::getConfig('mail_username'),
                'password' => SystemConfig::getConfig('mail_password'),
                'from' => SystemConfig::getConfig('mail_from'),
                'from_name' => SystemConfig::getConfig('mail_from_name'),
                'site_name' => SystemConfig::getConfig('site_name', '任务提醒系统'),
                'site_url' => SystemConfig::getConfig('site_url')
            ];

            // 发送邮件
            $this->sendReminderEmail($user, $reminder);

            // 更新提醒状态
            if (!$reminder->is_recurring) {
                // 非循环提醒，标记为已完结
                $reminder->is_finished = 1;
                $reminder->save();
                Log::info("非循环提醒 {$reminderId} 已标记为完结");
            } else {
                // 循环提醒，计算下次提醒时间
                $nextDueDate = $this->calculateNextDueDate($reminder->due_date, $reminder->recurrence_rule);
                
                // 检查是否超过结束日期
                if ($reminder->recurrence_end_date && $nextDueDate > $reminder->recurrence_end_date) {
                    $reminder->is_finished = 1;
                    Log::info("循环提醒 {$reminderId} 已达到结束日期，标记为完结");
                } else {
                    $reminder->due_date = $nextDueDate;
                    Log::info("循环提醒 {$reminderId} 更新下次提醒时间为：{$nextDueDate}");
                }
                $reminder->save();
            }

            return json([
                'success' => true,
                'reminder_id' => $reminderId,
                'is_recurring' => $reminder->is_recurring,
                'next_due_date' => $reminder->is_recurring && !$reminder->is_finished ? $reminder->due_date : null
            ]);

        } catch (\Exception $e) {
            Log::error("发送提醒失败: [提醒ID {$reminderId}] " . $e->getMessage());
            return json([
                'success' => false,
                'error' => "提醒ID {$reminderId}: " . $e->getMessage()
            ]);
        }
    }

    /**
     * 计算下次提醒时间
     */
    private function calculateNextDueDate($currentDueDate, $recurrenceRule)
    {
        $date = new \DateTime($currentDueDate);
        
        switch ($recurrenceRule) {
            case 'daily':
                $date->modify('+1 day');
                break;
            case 'weekly':
                $date->modify('+1 week');
                break;
            case 'monthly':
                $date->modify('+1 month');
                break;
            case 'yearly':
                $date->modify('+1 year');
                break;
            default:
                // 处理自定义规则，例如 "FREQ=WEEKLY;BYDAY=MO,WE,FR"
                if (strpos($recurrenceRule, 'FREQ=') === 0) {
                    // 这里可以添加更复杂的循环规则解析
                    // 例如：每周一三五、每月1号和15号等
                }
                break;
        }

        return $date->format('Y-m-d H:i:s');
    }

    /**
     * 发送提醒邮件
     */
    private function sendReminderEmail($user, $reminder)
    {
        try {
            $mailService = new \app\service\MailService();
            $result = $mailService->sendReminderEmail($user, $reminder);

            // 记录发送记录
            $record = new \app\model\ReminderSend;
            $record->user_id = $user->id;
            $record->reminder_id = $reminder->id;
            $record->send_type = \app\model\ReminderSend::TYPE_EMAIL;
            $record->send_status = \app\model\ReminderSend::STATUS_SUCCESS;
            $record->send_time = time();
            $record->save();

            return $result;
        } catch (\Exception $e) {
            // 记录失败记录
            $record = new \app\model\ReminderSend;
            $record->user_id = $user->id;
            $record->reminder_id = $reminder->id;
            $record->send_type = \app\model\ReminderSend::TYPE_EMAIL;
            $record->send_status = \app\model\ReminderSend::STATUS_FAILED;
            $record->error_message = mb_substr($e->getMessage(), 0, 255);  // 截取错误信息
            $record->send_time = time();
            $record->save();

            \think\facade\Log::error('提醒邮件发送失败：' . $e->getMessage());
            throw new \Exception('邮件发送失败：' . $e->getMessage());
        }
    }

    /**
     * 发送站内提醒
     */
    private function sendInternalReminder($user, $reminder)
    {
        try {
            // 站内提醒的具体实现...

            // 记录发送记录
            $record = new \app\model\ReminderSend;
            $record->user_id = $user->id;
            $record->reminder_id = $reminder->id;
            $record->send_type = \app\model\ReminderSend::TYPE_MESSAGE;
            $record->send_status = \app\model\ReminderSend::STATUS_SUCCESS;
            $record->send_time = time();
            $record->save();

            return true;
        } catch (\Exception $e) {
            // 记录失败记录
            $record = new \app\model\ReminderSend;
            $record->user_id = $user->id;
            $record->reminder_id = $reminder->id;
            $record->send_type = \app\model\ReminderSend::TYPE_MESSAGE;
            $record->send_status = \app\model\ReminderSend::STATUS_FAILED;
            $record->error_message = mb_substr($e->getMessage(), 0, 255);
            $record->send_time = time();
            $record->save();

            \think\facade\Log::error('站内提醒发送失败：' . $e->getMessage());
            throw new \Exception('站内提醒发送失败：' . $e->getMessage());
        }
    }

    /**
     * 记录提醒发送
     */
    private function recordReminderSend($userId, $reminderId, $sendType, $isSuccess, $errorMessage = null)
    {
        try {
            $record = new \app\model\ReminderSend;
            $record->user_id = $userId;
            $record->reminder_id = $reminderId;
            $record->send_type = $sendType;
            $record->send_status = $isSuccess ? 
                \app\model\ReminderSend::STATUS_SUCCESS : 
                \app\model\ReminderSend::STATUS_FAILED;
            $record->error_message = $errorMessage ? mb_substr($errorMessage, 0, 255) : null;
            $record->send_time = time();
            $record->save();
        } catch (\Exception $e) {
            \think\facade\Log::error('记录提醒发送失败：' . $e->getMessage());
        }
    }
} 